﻿using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.Features;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.Extensions.Primitives;
using JESAI.Application.Abstractions.Sys;
using JESAI.Application.Abstractions.Sys.Dtos;
using JESAI.Core.Http;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Dynamic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;


namespace JESAI.Framework.Middlewares
{
    public class LogMiddleware
    {
        private readonly RequestDelegate _next;
        private Stopwatch _stopwatch;
        private readonly ILogger<LogMiddleware> _logger;
        private readonly IAuditLogService _auditLogService;
        public LogMiddleware(RequestDelegate next,
            IAuditLogService auditLogService,
            ILogger<LogMiddleware> logger)
        {
            _next = next;
            _logger = logger;
            _auditLogService = auditLogService;
        }

        public async Task Invoke(HttpContext context)
        {
            _stopwatch = new Stopwatch();
            // 创建一个字典，用于保存所有的参数
            string id = Guid.NewGuid().ToString();


            Dictionary<string, string> parameters = await HttpRequestQueryParams.QueryParameters(context);

            // 获取客户端的浏览器信息和操作系统版本信息
            var userAgent = context.Request.Headers["User-Agent"].ToString();

            // 获取请求的客户端信息和 IP 地址
            var connection = context.Features.Get<IHttpConnectionFeature>();

            AuditLogDto auditLog = new AuditLogDto();
            var headers = context.Request.Headers; //
            auditLog.LocalPort = connection?.LocalPort.ToString();
            if (headers.ContainsKey("AppKey"))
            {
                auditLog.AppKey = headers["AppKey"].ToString();
            }
            auditLog.LocalIp = connection?.LocalIpAddress?.ToString();
            auditLog.LocalPort = connection?.LocalPort.ToString();
            auditLog.RemotePort = connection?.RemotePort.ToString();
            auditLog.RemoteIp = connection?.RemoteIpAddress.ToString();
            auditLog.Protocol = context.Request.Scheme;
            auditLog.UserAgent = userAgent;
            auditLog.SessionId = context.Connection.Id;
            auditLog.ConnectionId = id;
            auditLog.RequestPath = context.Request.Path;
            var requestParams = JsonConvert.SerializeObject(parameters);
            auditLog.RequestParams = requestParams.Length < 4000 ? requestParams : requestParams.Substring(0, 4000);
            _auditLogService.AddAuditLogAsync(auditLog);

            // 输出所有获取到的信息
            //Console.WriteLine("Method: " + context.Request.Method);
            //Console.WriteLine("Path: " + context.Request.Path);
            //Console.WriteLine("Parameters:");
            //foreach (var parameter in parameters)
            //{
            //    Console.WriteLine(parameter.Key + ": " + parameter.Value);
            //}
            //Console.WriteLine("Remote IP Address: " + remoteIpAddress);
            //Console.WriteLine("Remote Port: " + remotePort);
            //Console.WriteLine("Local Ip Address: " + localIpAddress);
            //Console.WriteLine("Local Port: " + localPort);
            //Console.WriteLine("Protocol: " + protocol);
            _stopwatch.Start();

            context.Items["stopWatch"] = _stopwatch;
            context.Items["connectionId"] = id;
            await _next(context);


        }
    }
}
